<script setup>
import { 
    ref, shallowRef, reactive, shallowReactive, readonly, shallowReadonly, computed, watch, watchEffect, watchPostEffect, watchSyncEffect, onWatcherCleanup,
    isRef, isReactive, isReadonly, isProxy,
    toRef, toRefs, toValue, unref, toRaw, markRaw,
    triggerRef, // 强制触发shallowRef的副作用
    customRef,  // 自定义ref
    onBeforeMount, onMounted, onBeforeUnmount, onUnmounted, onBeforeUpdate, onUpdated, onActivated, onDeactivated, 
    provide, inject,
    useAttrs, useSlots, useModel, useTemplateRef, useId,
} from 'vue'

const count = ref(0)

const doubleCount = computed(() => {
    return count.value * 2
})

const countMsg = ref('')
watch(count, (newCount, oldCount) => {
    countMsg.value = `${oldCount} -> ${newCount}`
}, {
    immediate: true, // 创建时执行一次
    deep: false,     // 深度监听
    flush: 'post',
    once: false,     // 是否只执行一次
})

const countWatchEffectMsg = ref('')
const { stop, pause, resume } = watchEffect(() => {
    countWatchEffectMsg.value = `${ count.value }`
}, {
    flush: 'post' // post 在组件渲染后执行; sync 在数据变更之后执行
})

const reactiveObj = reactive({
    x: 1,
    y: ['a', 'b', 'c'],
    z: {
        a: 1,
        b: 2
    }
})
const onRectiveChange = () => {
    reactiveObj.x++
    reactiveObj.y.push('x')
    reactiveObj.z.a++
}


const shallowRectiveObj = shallowReactive({
    x: 1,
    y: ['a', 'b', 'c'],
    z: {
        a: 1,
        b: 2
    }
})
const onShallowRectiveChange = () => {
    shallowRectiveObj.x++
    shallowRectiveObj.y.push('x')
    shallowRectiveObj.z.a++
}
</script>

<template>
    <div style="padding: 16px;">
        <div style="border-bottom: 1px solid #ccc;padding-bottom: 5px;">响应式API: ref, reactive, computed, watch, watchEffect, watchPostEffect, watchSyncEffect, readonly, onWatcherCleanup </div>

        <div style="padding: 10px 0;">
            <div style="padding-bottom: 10px;">ref: {{ count }}<el-button size="small" @click="count++" style="margin-left: 10px;">+</el-button></div>
            <div style="padding-bottom: 10px;">computed: {{  doubleCount }}, watch: {{ countMsg }}, watchEffect: {{ countWatchEffectMsg }}</div>
            <div style="padding-bottom: 10px;">reactive: {{ reactiveObj.x }} : {{ reactiveObj.y.join(',') }} : {{ reactiveObj.z.a }}<el-button size="small" @click="onRectiveChange" style="margin-left: 10px;">change</el-button></div>
            <div style="padding-bottom: 10px;">shallowReactive: {{ shallowRectiveObj.z.a }}<el-button size="small" @click="onShallowRectiveChange" style="margin-left: 10px;">change</el-button></div>
        </div>
    </div>
</template>